#ifndef BOARD
#define BOARD

#include "chess_base.hpp"
#include <map>
#include "move.hpp"
#include <memory>
#include <vector>

class Board {
public:
    using PiecePtr = std::shared_ptr<ChessPiece>;
    Board(Camp camp);
    Board(const Board &board);
    Board(const Board &&board);
    Board& operator=(const Board &board);
    Board& operator=(const Board &&board);
    ~Board();
    void init();
    void place(const PiecePtr piece, const Location loc);
    void remove(Location loc);
    void rotate();

    Camp side() const;
    const PiecePtr &at(const Location loc) const;
    int count(const Camp camp) const;
    void move(const Move &m);
    void undo();
    std::vector<Move> available_move() const;
    bool judge(Camp &winner) const;

    void print() const;
private:
    void _data_check() const;
    std::vector< std::vector<PiecePtr> > _board;
    std::map<PiecePtr, Location> _red;
    std::map<PiecePtr, Location> _black;
    Camp _side;

    std::vector<std::pair<Move, PiecePtr>> _undo_buffer;
};

#endif